home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 May: Tool Chest / Developer CD Series Tool Chest (Apple Computer)(May 1999).iso / Tool Chest / Games / Game Sample Code / ZAM 1.0a13 / GameSource / MissileSprite.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-16  |  8.4 KB  |  323 lines  |  [TEXT/KAHL]

  1. #include "ZAM.h"
  2. #include "GameAEvents.h"
  3. #include "MissileSprite.h"
  4. #include "SpriteFrameRates.h"
  5. #include "TankSprite.h"
  6. #include "GameSounds.h"
  7. #include "ZAMProtos.h"
  8.  
  9.  
  10. spriteLayerPtr MissileLayer;
  11. spriteLayerPtr RemoteMissileLayer;
  12. frameSetPtr    MissileFrameSetList;
  13. spritePtr    MissileSpriteList[kMaxMissiles];
  14. spritePtr    RemoteMissileSpriteList[kMaxMissiles];
  15.  
  16. typedef struct {
  17.     short    flags;
  18.     fixPt    loc;
  19.     fixPt    vel;
  20. } aeMissileInfo;
  21.  
  22. OSErr AppendMissilePositions(AppleEvent *ae)
  23. {
  24.     OSErr                err = 0;
  25.     short                index;
  26.     aeMissileInfo        missilePosList[kMaxMissiles];
  27.         
  28.     for(index = 0; index < kMaxMissiles; index++) {
  29.     
  30.         if(MissileSpriteList[index]->spriteFlags & kRemoteSpawn) {
  31.             MissileSpriteList[index]->spriteFlags &= ~kRemoteSpawn;
  32.             missilePosList[index].flags = 1;
  33.         } else if( MissileSpriteList[index]->spriteFlags & kRemoteDead ) {
  34.             MissileSpriteList[index]->spriteFlags &= ~kRemoteDead;
  35.             missilePosList[index].flags = 2;
  36.             MissileSpriteList[index]->inUse = false;
  37.         } else if(MissileSpriteList[index]->spriteFlags & kRemoteKilled) {
  38.             MissileSpriteList[index]->spriteFlags &= ~kRemoteKilled;
  39.             missilePosList[index].flags = 3;
  40.         } else {
  41.             missilePosList[index].flags = 0;
  42.         }
  43.         
  44.         missilePosList[index].loc = MissileSpriteList[index]->loc;
  45.         missilePosList[index].vel = MissileSpriteList[index]->vel;
  46.     }
  47.     
  48.     if(err == noErr) {
  49.         AEPutParamPtr(ae, keyMissilePos, typefixPtList, 
  50.                             &missilePosList, sizeof(missilePosList));
  51.         if(err != noErr) {
  52.             ErrMsgCode("\p Failure: AppendMissilePositions AEPutParamPtr",err);
  53.         }
  54.     }
  55.                 
  56.     return err;
  57. }
  58.  
  59.  
  60. OSErr ProcessMissilePositions(AppleEvent *ae)
  61. {
  62.     OSErr            err= 0;
  63.     short            index;
  64.     aeMissileInfo    missilePosList[kMaxMissiles];
  65.     long            len;
  66.     DescType        actualType;
  67.     
  68.     err = AEGetParamPtr(ae, keyMissilePos, typefixPtList, &actualType, 
  69.             &missilePosList, sizeof(missilePosList), &len);
  70.     if(err != noErr) {
  71.         ErrMsgCode("\p Failed: AEMoveRemoteMissile keyDir, typeShortInteger",err);
  72.     }
  73.     
  74.     if(err == noErr) {
  75.         for(index = 0; index < kMaxMissiles; index++) {
  76.             if(missilePosList[index].flags == 1) {
  77.                 FireMissileVelocity(&missilePosList[index].vel,
  78.                              missilePosList[index].loc.h, missilePosList[index].loc.v, 
  79.                              true, index);             
  80.             } else if(missilePosList[index].flags == 2) {
  81.                 RemoteMissileSpriteList[index]->inUse = false;
  82.                 RemoteMissileSpriteList[index]->visible = false;
  83.                 RemoteMissileSpriteList[index]->spriteFlags |= kNeedsToBeErased;
  84.                 RemoteMissileSpriteList[index]->ownerLayer->layerFlags |= kLayerDirty;
  85.                 RemoteMissileSpriteList[index]->inUse = false;
  86.                 StartExplosionHere(gGame, missilePosList[index].loc.h, missilePosList[index].loc.v);
  87.             } else if(missilePosList[index].flags == 3) {
  88.                 StopAllSounds();
  89.                 SoundDisable();
  90.                 gDead = true;
  91.                 gDeadTime = TickCount();
  92.             } else if(RemoteMissileSpriteList[index]->inUse) {
  93.                 RemoteMissileSpriteList[index]->moveTask.taskFlag = true;
  94.                 RemoteMissileSpriteList[index]->remoteLoc = missilePosList[index].loc;
  95.             }
  96.         }    
  97.     }
  98.     return err;
  99. }
  100.  
  101. void CheckMissileColissions(gamePtr game)
  102. {
  103.     if(MissileLayer->activeCount)
  104.         CollideSpriteLayer( MissileLayer, gTankLayer[game->remoteTankIndex]);
  105. }
  106.  
  107. void MissileColissionHandler( spritePtr spr, spritePtr obj, Rect *colArea)
  108. {
  109.     if( (RECT_WD(*colArea) >= kCollThresh) && (RECT_HT(*colArea) >= kCollThresh) ) {
  110.         spr->visible = false;
  111.         spr->spriteFlags |= kNeedsToBeErased;
  112.         spr->ownerLayer->layerFlags |= kLayerDirty;
  113.         StartExplosionHere(gGame, spr->loc.h, spr->loc.v);
  114.         SetSpriteFrameCallback(spr,GetNextSpriteFrameIndex(spr),HaltMissileFrameTask);
  115.         spr->spriteFlags |= kRemoteDead;
  116.     }
  117. }
  118.  
  119. Boolean HaltMissileFrameTask(spritePtr spr)
  120. {
  121.     SetSpriteFrameCallback(spr,spr->frameList->finfo.frameIndex,nil);
  122.     spr->visible = false;
  123.     spr->ownerLayer->activeCount--;
  124.     return false;
  125. }
  126.  
  127. Boolean MissileMoveFilter(spritePtr spr)
  128. {
  129.     Rect    junk;
  130.     gamePtr game;
  131.     Boolean result = true;
  132.     
  133.     game = (gamePtr)spr->refCon;
  134.     
  135.     spr->data--;
  136.     /* should also check if the sprite has left the screen and then kill it */
  137.     if(!spr->data  )  {
  138.         spr->visible = false;
  139.         spr->spriteFlags |= kNeedsToBeErased | kRemoteDead;
  140.         spr->ownerLayer->layerFlags |= kLayerDirty;
  141.         SetSpriteFrameCallback(spr,GetNextSpriteFrameIndex(spr),HaltMissileFrameTask);
  142.         StartExplosionHere(gGame, spr->loc.h, spr->loc.v);
  143.         spr->spriteFlags |= kRemoteDead;
  144.         result = false;
  145.     }
  146.  
  147.     return result;
  148. }
  149.  
  150.  
  151. void LoadMissileSprites(gamePtr game)
  152. {
  153.     OSErr            err;
  154.     short            ref;
  155.     short            i,iconID;
  156.     frameSetPtr        missileFrameSet;
  157.     short            numMissileFrames;
  158.     
  159.     
  160.     ref = OpenResFile("\pFireBallFrames.rsrc");
  161.     if(err = ResError()) {
  162.         ErrMsgCode("\pCould Not Open MissileFrames file!.",err);
  163.         ExitToShell();
  164.     }
  165.     
  166.     numMissileFrames = Count1Resources('cicn');
  167.     
  168.     if(err == noErr) {
  169.         if(err == noErr) {
  170.             err = CreatePICTIconFrameSet(&MissileFrameSetList, 128, numMissileFrames);
  171.             if(err != noErr) {
  172.                 ErrMsgCode("\pCreateColorIconFrameSet failed.",err);
  173.             }
  174.             /*
  175.                 Setting the ctseed to the same as the other color tables,
  176.                 so that no colors will be mapped.
  177.             */
  178.             if(err == noErr)
  179.                 SetFrameSetCTSeed(MissileFrameSetList,game->gameCTSeed);
  180.  
  181.         }
  182.     }
  183.  
  184.  
  185.     CloseResFile(ref);
  186.  
  187.     err = CreateSpriteLayer(&MissileLayer, game->tween,game->backdrop, game->gameWind);
  188.     if(err != noErr) {
  189.         ErrMsgCode("\pCreateSpriteLayer failed.",err);
  190.         ExitToShell();
  191.     }
  192.     
  193.     for(i = 0; i < kMaxMissiles; i++) {
  194.     
  195.         if(err == noErr) {
  196.             err = CreateEmptySprite(MissileLayer,
  197.                                 &MissileSpriteList[i],    /* returned sprite here */
  198.                                 kDefaultFrameAdvance,
  199.                                 kMissileMoveTime,     /* time between movement */
  200.                                 kMissileFrameTime,     /* time between frame change */
  201.                                 (long)game);
  202.     
  203.             if(err != noErr) {
  204.                 ErrMsgCode("\pCreateEmptySprite failed.",err);
  205.             } else {
  206.                 err = CreateEmptyFrameSet(&MissileSpriteList[i]->frameList,numMissileFrames);
  207.             }
  208.  
  209.             MissileSpriteList[i]->moveHandler = MissileMoveFilter;
  210.             MissileSpriteList[i]->spriteID = i;
  211.             MissileSpriteList[i]->inUse = false;
  212.             MissileSpriteList[i]->collideHandler = (collisionProc)MissileColissionHandler;
  213.         }
  214.     }
  215.  
  216.  
  217.     err = CreateSpriteLayer(&RemoteMissileLayer, game->tween, game->backdrop, game->gameWind);
  218.     if(err != noErr) {
  219.         ErrMsgCode("\pCreateSpriteLayer failed.",err);
  220.         ExitToShell();
  221.     }
  222.  
  223.     /* now build remote missiles */
  224.     for(i = 0; i < kMaxMissiles; i++) {
  225.     
  226.         if(err == noErr) {
  227.             err = CreateEmptySprite(RemoteMissileLayer,
  228.                                 &RemoteMissileSpriteList[i],    /* returned sprite here */
  229.                                  kRemoteSprite | kDefaultFrameAdvance | kRemoteUpdate,
  230.                                 // kDefaultFrameAdvance ,
  231.                                 kMissileFrameTime,     /* time between frame change */
  232.                                 kMissileMoveTime,     /* time between movement */
  233.                                 (long)game);
  234.     
  235.             if(err != noErr) {
  236.                 ErrMsgCode("\pCreateEmptySprite failed.",err);
  237.             } else {
  238.                 err = CreateEmptyFrameSet(&RemoteMissileSpriteList[i]->frameList,numMissileFrames);
  239.             }
  240.             RemoteMissileSpriteList[i]->spriteID = i;
  241.             RemoteMissileSpriteList[i]->moveHandler = MissileMoveFilter;
  242.         }
  243.         
  244.     }
  245.     
  246. }
  247.  
  248.  
  249.  
  250. spritePtr GetMissileSprite(Boolean network)
  251. {
  252.     short i;
  253.     
  254.     for(i = 0; i < kMaxMissiles; i++)
  255.         if(MissileSpriteList[i]->inUse == false) {
  256.             MissileSpriteList[i]->inUse = true;
  257.             MissileSpriteList[i]->ownerLayer->activeCount++;
  258.             return MissileSpriteList[i];
  259.         }
  260.     
  261.     return nil;
  262. }
  263.  
  264. void FireMissileVelocity(fixPt *vel, Fixed h, Fixed v, Boolean network, short missileNum)
  265. {
  266.     FireMissile(VelocityToDirection(vel),h,v,network,missileNum);
  267. }
  268.  
  269. void FireMissile( short dir, Fixed h, Fixed v, Boolean network, short missileNum)
  270. {
  271.     fixPt        vel;
  272.     spritePtr    missile;
  273.     
  274.  
  275.     if(network == false)
  276.         missile = GetMissileSprite(network);
  277.     else {
  278.         missile = RemoteMissileSpriteList[missileNum];
  279.         missile->ownerLayer->activeCount++;
  280.         missile->inUse = true;
  281.         missile->remoteLoc.h = h;
  282.         missile->remoteLoc.v = v;
  283.     }
  284.     
  285.     if(missile) {
  286.         (void)PlaySndAsynchChannel( kFireSnd, kShotChan, kStdPriority);
  287. //
  288. //    taking out because adding kRemoteSpawn bit
  289. //        if(network == false) 
  290. //            NetworkFireMissile(gGame, dir, h, v, missile->spriteID);
  291.  
  292.         if(network == false)
  293.             missile->spriteFlags |= kRemoteSpawn;
  294.  
  295.         missile->data = kMissileLife;
  296.         if( ((missile->frameTask.timer.qType & TaskActiveFlag) != 0) 
  297.             ||  ((missile->moveTask.timer.qType & TaskActiveFlag) != 0)) {
  298.             HideSprite(missile);
  299.             StopSpriteAction(missile);    
  300.         }
  301.         
  302.         SetSpriteFrameSet(missile,MissileFrameSetList);
  303.     
  304.         DirectionToVelocity( dir, &vel);
  305.         
  306.         vel.h = FixMul(vel.h,ff(12));
  307.         vel.v = FixMul(vel.v,ff(12));
  308.         SetSpriteVelocity(missile, vel.h , vel.v);
  309.     
  310.         SetSpriteLoc(missile, h, v);
  311.     
  312.         missile->visible = true;
  313.  
  314.         if(network) {
  315.             StartRemoteSpriteAction(missile);
  316.         } else {
  317.             StartSpriteAction(missile);
  318.         }
  319.         
  320.     }
  321. }
  322.  
  323.